package us.versus.them.stickler.graphics;

#if flash

import flash.events.Event;
import flash.events.MouseEvent;
import flash.display.Graphics;

import us.versus.them.stickler.Point;

/**
 *
 * This class provides a thin layer between haxe and flash so
 * the app can be flash-agnostic.
 *
 */
class FlashGraphics implements ThinGraphics {

	private var _enterFrame : FlashEventAdapter< Event >;
	private var _mouseDown  : FlashEventAdapter< MouseEvent >;
	private var _mouseUp    : FlashEventAdapter< MouseEvent >;
	private var _mouseMove  : FlashEventAdapter< MouseEvent >;

	public function new() {
	}

	public function clear() {
		flash.Lib.current.graphics.clear();
	}

	public function drawBox( point : Point, size : Point, color : Int  ) {
		this.drawBoxGraphics( flash.Lib.current.graphics, point, size, color );
	}

	public function drawBoxGraphics( graphics : flash.display.Graphics, point : Point, size : Point, color : Int ) {
		graphics.beginFill( color );
		graphics.lineStyle( 4, 0x000020 );
		graphics.drawRect( point.x -   size.x / 2 , point.y - size.y / 2 , size.x , size.y );
	}

	public function drawLine( start : Point, stop : Point ) {
		this.drawLineGraphics( flash.Lib.current.graphics, start, stop );
	}

	public function drawLineGraphics( graphics : flash.display.Graphics, start : Point, stop : Point ) {
		graphics.beginFill( 0xDDDDFF );
		graphics.lineStyle( 4, 0x000020 );
		graphics.moveTo( start.x, start.y );
		graphics.lineTo( stop.x, stop.y );
	}

	public function addEnterFrame( enterFrame : Void -> Void ) {
		if ( null == _enterFrame ) {
			_enterFrame = new FlashEventAdapter< Event >( noarg );
			flash.Lib.current.addEventListener( 
				flash.events.Event.ENTER_FRAME
				, _enterFrame.call
			);
		}
		_enterFrame.add( enterFrame );
	}

	public function addMouseDown( mouseDown : Int -> Int -> Void ) {
		if ( null == _mouseDown ) {
			_mouseDown = new FlashEventAdapter< MouseEvent >( mouseEventCoords );
			flash.Lib.current.stage.addEventListener( 
				flash.events.MouseEvent.MOUSE_DOWN
				, _mouseDown.call
			);
		}
		_mouseDown.add( mouseDown );
	}


	public function addMouseUp( mouseUp : Int -> Int -> Void ) {
		if ( null == _mouseUp ) {
			_mouseUp = new FlashEventAdapter< MouseEvent >( mouseEventCoords );
			flash.Lib.current.stage.addEventListener( 
				flash.events.MouseEvent.MOUSE_UP
				, _mouseUp.call
			);
		}
		_mouseUp.add( mouseUp );
	}

	public function addMouseMove( mousemove : Int -> Int -> Void ) {
		if ( null == _mouseMove ) {
			_mouseMove = new FlashEventAdapter< MouseEvent >( mouseEventCoords );
			flash.Lib.current.stage.addEventListener( 
				flash.events.MouseEvent.MOUSE_MOVE
				, _mouseMove.call
			);
		}
		_mouseMove.add( mousemove );
	}


	public static function noarg( callbacki : Dynamic , event:Event ) {
		callbacki();
	}

	public static function mouseEventCoords( callbacki : Dynamic , event : MouseEvent ) {
		callbacki( event.localX, event.localY );
	}
}

#end
